#pragma once
#include <iostream>
#include <vector>
#include <string>
#include <Python.h>
#include <thread>
#include <mutex>
#include <cstring>  // 用于 strerror

class PythonScriptManager {
private:
    std::vector<std::string> scriptPaths;
    std::vector<std::thread> scriptThreads;
    bool isInitialized;
    mutable std::mutex mtx;
    PyThreadState* mainThreadState;  // 新增：保存主线程的Python状态

    void runSingleScript(const std::string& scriptPath) {
        if (!isInitialized) {
            std::cerr << "Python未初始化，无法执行脚本：" << scriptPath << std::endl;
            return;
        }

        // 子线程获取GIL
        PyGILState_STATE gilState = PyGILState_Ensure();

        FILE* file = fopen(scriptPath.c_str(), "r");
        if (!file) {
            std::cerr << "无法打开脚本文件：" << scriptPath << "，错误：" << strerror(errno) << std::endl;
            PyGILState_Release(gilState);
            return;
        }

        std::cout << "开始执行脚本：" << scriptPath << std::endl;
        int result = PyRun_SimpleFile(file, scriptPath.c_str());
        fclose(file);

        if (result != 0) {
            std::cerr << "脚本执行失败：" << scriptPath << std::endl;
            if (PyErr_Occurred()) PyErr_Print();
        }
        else {
            std::cout << "脚本执行成功：" << scriptPath << std::endl;
        }

        // 释放GIL
        PyGILState_Release(gilState);
    }

public:
    PythonScriptManager() : isInitialized(false), mainThreadState(nullptr) {
        // 1. 初始化Python
        Py_Initialize();
        if (!Py_IsInitialized()) {
            std::cerr << "Python初始化失败！" << std::endl;
            return;
        }

        // 2. 显式初始化线程支持，并释放主线程GIL（关键修复）
/*        PyEval_InitThreads(); */ // 初始化线程，主线程暂时持有GIL
        mainThreadState = PyEval_SaveThread();  // 释放主线程GIL，保存状态

        isInitialized = true;
        std::cout << "Python解释器初始化成功（线程支持已启用）" << std::endl;
    }

    ~PythonScriptManager() {
        // 1. 恢复主线程GIL（关键修复）
        if (mainThreadState != nullptr) {
            PyEval_RestoreThread(mainThreadState);  // 恢复主线程的GIL状态
        }

        // 2. 等待所有脚本线程结束
        for (auto& th : scriptThreads) {
            if (th.joinable()) {
                th.join();
            }
        }

        // 3. 关闭Python
        if (isInitialized) {
            Py_Finalize();
            std::cout << "Python解释器已关闭" << std::endl;
        }
    }

    bool addScript(const std::string& scriptPath) {
        std::lock_guard<std::mutex> lock(mtx);

        if (!isInitialized) {
            std::cerr << "Python未初始化，无法添加脚本" << std::endl;
            return false;
        }

        for (const auto& path : scriptPaths) {
            if (path == scriptPath) {
                std::cerr << "脚本已添加：" << scriptPath << std::endl;
                return false;
            }
        }

        // 新增：打印线程ID（C++11及以上支持）
        auto thread_func = [this, scriptPath]() {
            std::cout << "线程ID: " << std::this_thread::get_id()
                << " 开始执行脚本：" << scriptPath << std::endl;
            this->runSingleScript(scriptPath);
            };

        scriptPaths.push_back(scriptPath);
        scriptThreads.emplace_back(&PythonScriptManager::runSingleScript, this, scriptPath);
        std::cout << "脚本已添加并启动：" << scriptPath << "（总脚本数：" << scriptPaths.size() << "）" << std::endl;
        return true;
    }
};